# recommendation/views.py
from django.shortcuts import get_object_or_404
from rest_framework.decorators import api_view
from rest_framework.response import Response
from django.db.models import Count

from management.middleware import skip_middleware_user_activity
from problems.models import Problem
from problems.serializers import ProblemSerializer
from utils.logging_utils import log_request_response
from .services import clear_user_solved_problems, get_user_problem_numbers
from rest_framework.authtoken.models import Token
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import authentication_classes, permission_classes
from django.contrib.auth.models import User
from .models import User as CustomUser, SolvedProblem  # 自定义的User表
from rest_framework import status
from rest_framework_simplejwt.authentication import JWTAuthentication


@api_view(['GET'])
@authentication_classes([JWTAuthentication])  # 使用 Token 认证
@permission_classes([IsAuthenticated])
@log_request_response
def frontend_get_user_tag_difficulty_analysis(request):
    user = request.user

    # 查询用户已解决的问题，按标签和难度分组统计
    tag_data = (
        SolvedProblem.objects
        .filter(user=user)
        .values('problem__tags__tag_name', 'problem__difficulty')
        .annotate(count=Count('id'))
    )

    # 构造统计数据结构
    tag_difficulty_data = {}
    total_problems = 0

    for entry in tag_data:
        tag_name = entry['problem__tags__tag_name']
        difficulty = entry['problem__difficulty'] or '暂未评定'
        count = entry['count']
        total_problems += count

        # 初始化标签数据结构
        if tag_name not in tag_difficulty_data:
            tag_difficulty_data[tag_name] = {
                'total': 0,
                'difficulties': {}
            }

        # 累计标签总数
        tag_difficulty_data[tag_name]['total'] += count

        # 设置难度的数据结构和问题列表
        if difficulty not in tag_difficulty_data[tag_name]['difficulties']:
            tag_difficulty_data[tag_name]['difficulties'][difficulty] = {
                'count': count,
                'problems': list(
                    SolvedProblem.objects
                    .filter(user=user, problem__tags__tag_name=tag_name, problem__difficulty=difficulty)
                    .values_list('problem__problem_number', 'problem__problem_name')
                )
            }
        else:
            tag_difficulty_data[tag_name]['difficulties'][difficulty]['count'] += count

    return Response({
        'tag_difficulty_data': tag_difficulty_data,
        'total_problems': total_problems
    })


@api_view(['GET'])
@authentication_classes([JWTAuthentication])  # 使用 Token 认证
@permission_classes([IsAuthenticated])
@log_request_response
def frontend_get_user_solved_problems_info(request):
    try:
        # 获取当前用户
        user = request.user

        # 获取该用户已解决题目的列表
        solved_problems = SolvedProblem.objects.filter(user=user).select_related('problem')
        problem_data = []

        for solved_problem in solved_problems:
            problem = solved_problem.problem
            # 序列化每个题目信息
            serialized_problem = ProblemSerializer(problem).data
            problem_data.append(serialized_problem)

        return Response({
            "solved_problems": problem_data
        }, status=status.HTTP_200_OK)

    except User.DoesNotExist:
        return Response({"error": "User not found."}, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@authentication_classes([JWTAuthentication])  # 使用 Token 认证
@permission_classes([IsAuthenticated])  # 仅允许已认证的用户访问
@log_request_response
def crawl_user_problems(request):
    """
    根据当前登录用户的 luogu_uid 爬取/更新用户通过的题目编号存入数据库中，并返回 JSON 响应。
    """
    try:
        # 获取当前已认证的用户
        current_user = request.user
        problem_numbers = SolvedProblem.fetch_and_store_user_problems_by_id(current_user.id)

        return Response({
            "message": f"Successfully fetched and stored {problem_numbers} problems for user {current_user.username}"
        }, status=200)
    except User.DoesNotExist:
        return Response({"error": "User not found."}, status=404)
    except Exception as e:
        return Response({"error": str(e)}, status=500)


# 返回用户已经通过的题目列表
@api_view(['GET'])
@authentication_classes([JWTAuthentication])  # 使用 Token 认证
@permission_classes([IsAuthenticated])  # 仅允许已认证的用户访问
@log_request_response
def show_user_problems(request):
    """
    获取当前登录用户的通过题目列表并返回。
    """
    try:
        current_user = request.user
        solved_problems = current_user.solved_problems.all()
        problem_numbers = [sp.problem.problem_number for sp in solved_problems]

        return Response({
            "solved_problems": problem_numbers
        }, status=200)
    except CustomUser.DoesNotExist:
        return Response({"error": "User not found."}, status=404)
    except Exception as e:
        return Response({"error": str(e)}, status=500)

from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication
from django.shortcuts import get_object_or_404
from .models import RecommendationQueue

@api_view(['GET'])
@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
@log_request_response
def pop_recommendation(request):
    """弹出并返回用户推荐队列中的第一个题目"""

    user = request.user
    recommendation_queue = get_object_or_404(RecommendationQueue, user=user)
    # 类似于recommendation_queue = user.recommendation_queue，但上面写法若找不到满足条件对象则直接抛出http404
    problem_number = recommendation_queue.dequeue()
    if problem_number:
        return Response({"problem_number": problem_number}, status=200)
    return Response({"error": "No problems in the recommendation queue"}, status=404)


@api_view(['POST'])  # 使用 POST 请求，因为这是一个修改数据的操作
@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
@log_request_response
def randomize_recommendation_queue(request):
    """
    随机重置并填充认证用户的推荐队列。
    """
    user = request.user
    recommendation_queue = get_object_or_404(RecommendationQueue, user=user)

    # 重置并随机填充推荐队列
    recommendation_queue.reset_and_randomize_queue()

    return Response({
        "message": f"Recommendation queue for {user.username} has been randomized and repopulated."
    }, status=200)

@api_view(['POST'])
@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
@log_request_response
def initialize_recommendation_queue(request):
    """
    创建或重置用户的推荐队列。
    """
    user = request.user

    # 尝试获取现有的推荐队列或创建一个新的
    # 同时接收函数或方法返回的多个值
    recommendation_queue, created = RecommendationQueue.objects.get_or_create(user=user)

    if created:
        # 如果是新创建的，可以选择随机填充推荐队列
        recommendation_queue.reset_and_randomize_queue()
        message = "Recommendation queue has been created and populated."
    else:
        # 如果已经存在，可以选择不做改动，或者也可以重置
        message = "Recommendation queue already exists."

    return Response({
        "message": message
    }, status=200)


@api_view(['POST'])  # 使用POST请求来处理数据清空操作
@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])  # 仅允许已认证的用户执行操作
@log_request_response
def clear_solved_problems(request):
    # 清空用户的做题记录
    user = request.user  # 获取当前认证的用户

    # 调用前面定义的函数清空该用户的已解决题目记录
    deleted_count = clear_user_solved_problems(user)

    # 返回响应给用户
    return Response({
        "message": f"Successfully cleared {deleted_count} solved problems.",
        "deleted_count": deleted_count
    })

@api_view(['POST'])
@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
@log_request_response
def update_problems_from_user(request):
    try:
        user = request.user  # 获取当前认证的用户
        # 爬取问题数据
        problems = SolvedProblem.fetch_and_store_user_problems_by_id(user.id)  # 这需要调整以返回问题实例列表
        # 序列化问题数据
        serializer = ProblemSerializer(problems, many=True)
        # 返回成功响应
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    except CustomUser.DoesNotExist:
        return Response({"error": "User not found"}, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


from django.http import JsonResponse
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication
from recommendation_pool.models import RecommendationQueue


@api_view(['DELETE'])
@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
@log_request_response
def delete_recommendation_queue(request):
    user = request.user  # 获取当前已认证的用户

    try:
        # 查找用户的推荐队列实例
        recommendation_queue = RecommendationQueue.objects.get(user=user)
        recommendation_queue.delete()  # 删除该用户的推荐队列

        return JsonResponse({
            'message': 'Recommendation queue deleted successfully.'
        }, status=200)

    except RecommendationQueue.DoesNotExist:
        return JsonResponse({
            'error': 'Recommendation queue not found for this user.'
        }, status=404)

    except Exception as e:
        return JsonResponse({
            'error': f'An error occurred while deleting the recommendation queue: {str(e)}'
        }, status=500)


from django.http import JsonResponse
from django.views import View


@api_view(['GET'])
@skip_middleware_user_activity
@log_request_response
def get_user_problem_numbers_view(request, uid):

    try:
        # 调用爬虫函数获取用户已通过题目编号
        problem_numbers = get_user_problem_numbers(uid)
        # 返回爬取结果
        return JsonResponse({
            "uid": uid,
            "problem_numbers": problem_numbers,
            "status": "success" if problem_numbers else "failed",
        })
    except Exception as e:
        # 发生错误时返回错误信息
        return JsonResponse({
            "status": "error",
            "message": str(e)
        })
